package slave.sspGUI;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.FileReader;
import java.io.Reader;
import java.util.Hashtable;
import java.util.Observable;
import java.util.Observer;
import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSlider;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.WindowConstants;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import slave.SlaveStreamProvider;

/**
 * This code was edited or generated using CloudGarden's Jigloo
 * SWT/Swing GUI Builder, which is free for non-commercial
 * use. If Jigloo is being used commercially (ie, by a corporation,
 * company or business for any purpose whatever) then you
 * should purchase a license for each developer using Jigloo.
 * Please visit www.cloudgarden.com for details.
 * Use of Jigloo implies acceptance of these licensing terms.
 * A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
 * THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
 * LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
 */
public class StreamProviderMonitor extends javax.swing.JFrame implements Observer{
	/**
	 * 
	 */
	private static final long serialVersionUID = -3466742133583610821L;
	private Hashtable <String,JPanel> activeClient = new Hashtable<String,JPanel>();
	private JTabbedPane jTabbedPane;
	private JSplitPane jSplitPane;
	private JPanel clientsActivePanel;
	private JScrollPane jScrollclientsActivePanel;
	public SlaveStreamProvider ssp;
	private TopPanel header;
	private boolean init =true;
	public  String set = "NONSETTATO";
	public JTextArea history;
	public Vector <String> message;
	private RSyntaxTextArea jobXml = null;	
	private RSyntaxTextArea gatewayXml = null;
	private JPanel jHotSetting;
	private JPanel jPanel_SettingValues;
	private JButton jButton_Update;
	private JLabel jLabel_Empty2;
	private JSlider jSlider_ClientsWeight;
	private JTextField jTextField_ClientsWeight;
	private JLabel jLabel1;
	private boolean first = true;
	private JSlider jSlider_RssiWeight;
	private JTextField jTextField_ValueOfRssi;
	private JLabel jLabel3;
	private JLabel jLabel2;
	private JLabel jLabel4;
	private JLabel jLabel5;
	private JSeparator jSeparator1;
	private JLabel jLabel6;

	{
		//Set Look & Feel
		try {
			javax.swing.UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
		} catch(Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Auto-generated main method to display this JFrame
	 */
	public static void main(String[] args) {
	}

	public StreamProviderMonitor(SlaveStreamProvider ssp) {
		super();
		this.ssp=ssp;	
		initGUI();
		setVisible(true);
		setResizable(false);	
	}

	public StreamProviderMonitor getMonitor(){
		return this;	
	}


	private JPanel makeClientJPanel(String mac,String port,String stack, String lenght, String kbps, String file){
		System.out.println("[SystemOutputStreamMonitor] Aggiunto nuovo JPanel per "+mac);
		ClientJPanel client = new ClientJPanel(ssp,mac,port,stack,lenght,kbps,file);
		Border border = BorderFactory.createTitledBorder("");
		client.setBorder(border);	
		clientsActivePanel.add(client);
		validate();
		client.setPreferredSize(new Dimension(300,130));
		client.getVelocity().setPreferredSize(new java.awt.Dimension(27, 14));
		client.getStreamBar().setPreferredSize(new java.awt.Dimension(226, 19));
		client.getStop().setPreferredSize(new java.awt.Dimension(62, 23));
		client.getMac().setPreferredSize(new java.awt.Dimension(163, 12));
		client.getPort().setPreferredSize(new java.awt.Dimension(125, 21));
		client.getFile().setPreferredSize(new java.awt.Dimension(163, 20));
		activeClient.put(mac,client);
		history.append("GUI: add panel for "+mac+"\n");
		history.setCaretPosition(history.getDocument().getLength());
		return null;
	}

	public void updateMonitor(String msg,String mac, String port,String stack, String file, String kbps, String lenght, String secondsTransmitted){

		try{
			deviceNumber(stack);
			for (int k=0;k<=activeClient.size();k++){
				if(activeClient.containsKey(mac)){
					activeClient.get(mac);	
					ClientJPanel client = (ClientJPanel) activeClient.get(mac);		
					if(msg.equals("update")){
						if(!secondsTransmitted.equals("0.0")){
							client.getStreamBar().setValue(Integer.parseInt(secondsTransmitted));	
						}
						client.getVelocity().setHorizontalAlignment(SwingConstants.RIGHT);
						String tmp=kbps.substring (0, 6 > kbps.length() ? kbps.length() : 6);
						client.getVelocity().setText(tmp);
						//Controllo dei dispositivi utilizzati
					}else {// se il messaggio corrisponde a Delete, devo rimuovere il client
						clientsActivePanel.remove(client);	
						activeClient.remove(mac);
						history.append("GUI: Received from SSM delete "+mac+"\n");
						history.setCaretPosition(history.getDocument().getLength());
						repaint();
					}		
				}else {//JFrameClient non presente dovrà essere aggiunto!!
					if(!msg.equals("delete")){
						makeClientJPanel(mac, port,stack, lenght, kbps, file);	
					}
				}
			}
		}catch(Exception e){
			e.printStackTrace();	
			validate();
		}

	}

	private String deviceNumber(String stack){	
		try{
			if(!activeClient.isEmpty() && stack!=null){
				TopPanel top = (TopPanel) clientsActivePanel.getComponent(0);
				for(int k=1;k<=activeClient.size();k++){
					ClientJPanel client = (ClientJPanel) clientsActivePanel.getComponent(k);
					String stack_c = client.getStack().getText().substring(21);
					if(!stack_c.equals(stack)){
						top.getDeviceUsed().setText("2");	
						return null;
					}else top.getDeviceUsed().setText("1");
				}
			}
		}catch(Exception ex){
			ex.printStackTrace();
		}
		return null;
	}

	public void initGUI() {
		try {
			this.setTitle("Provider Stream Monitor");
			this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
			{
				jSplitPane = new JSplitPane();
				getContentPane().add(jSplitPane, BorderLayout.CENTER);
				{
					jScrollclientsActivePanel = new JScrollPane();
					jScrollclientsActivePanel.setPreferredSize(new java.awt.Dimension(195, 268));
					{
						clientsActivePanel = new JPanel();
						jScrollclientsActivePanel.setViewportView(clientsActivePanel);
						clientsActivePanel.setPreferredSize(new java.awt.Dimension(195, 900));
						{
							header = new TopPanel(this,ssp);
							clientsActivePanel.add(header);	
						}
					}
				}
				jSplitPane.setDividerLocation(350);
				jSplitPane.add(jScrollclientsActivePanel, JSplitPane.LEFT);
				jSplitPane.add(getJTabbedPane1(), JSplitPane.RIGHT);
			}	
			setSize(800,500);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public JTabbedPane getJTabbedPane1() {
		if(jTabbedPane == null) {
			jTabbedPane = new JTabbedPane();
			history = new JTextArea();
			JScrollPane h_scroll = new JScrollPane(history);
			jTabbedPane.addTab("Event History",h_scroll);
			jobXml = new RSyntaxTextArea();
			gatewayXml = new RSyntaxTextArea();
			jTabbedPane.addTab("job.xml",jobXml);
			jTabbedPane.addTab("gateway.xml", gatewayXml);
			readXml();
			jTabbedPane.addTab("Settings", null, getJHotSetting(), null);
		}
		return jTabbedPane;
	}
	public void showCodec(Vector <String> message ){
		history.append("GUI: Call showcodec"+"\n");
		history.setCaretPosition(history.getDocument().getLength());
		if(activeClient.isEmpty()){
			header.getCurrentCodec().setText(message.elementAt(ssp.currentQuality+1));	
		}
		for(int k=1;k<=message.size()-1;k++){
			header.getCoding().addItem(message.elementAt(k));
		}	
	}

	public void readXml(){
		Reader readerJob = null;
		Reader readerGateway = null;
		try{
			if(init){
				jobXml.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
				jobXml.setText("waiting job..");
				gatewayXml.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JAVA);
				gatewayXml.setText("no client..");
				RSyntaxTextArea.setTemplatesEnabled(true);	
				init=false;
			}
			readerJob = new FileReader("./slaveTmp/job.xml");
			jobXml.read(readerJob, null);
			readerGateway = new FileReader("./xml/gatewayCopy.xml");
			gatewayXml.read(readerGateway, null);
			readerJob.close();
			readerGateway.close();
		}
		catch(Exception e){	
		}		
	}

	@SuppressWarnings("unchecked")
	public void change(Vector m){
		this.message =  m;
		String msg = message.elementAt(0);
		if(msg.equals("update")){
			String mac = message.elementAt(1);
			String port = message.elementAt(2);
			String stack = message.elementAt(3);
			String file = message.elementAt(4);
			String kbps = message.elementAt(5);
			String lenght = message.elementAt(6);
			String secondsTransmitted = message.elementAt(7);	
			updateMonitor(msg, mac,port,stack,file, kbps, lenght, secondsTransmitted);
		}
		if(msg.equals("delete")){
			String mac = message.elementAt(1);	
			updateMonitor(msg, mac,null,null,null,null,null,null);
		}
		if(msg.equals("EVT")){//Update EVT History
			history.append(message.elementAt(1)+"\n");
			history.setCaretPosition(history.getDocument().getLength());

		}
		if(msg.equals("coding") && first){//Coding
			if(!set.equals("SETTATO")){
				set="SETTATO";
				showCodec(message);
				first = false;
			}
		}	
		message.clear();
	}
	@SuppressWarnings("unchecked")
	@Override
	public void update(Observable o, Object arg) {
		System.out.println("[StreamProviderMonitor] Notify: " + arg);		
		readXml();
		change((Vector ) arg);
	}

	public JPanel getJHotSetting() {
		if (jHotSetting==null) {
			jHotSetting = new JPanel();
			jHotSetting.setLayout(null);
			jHotSetting.add(getJLabel4());
			jHotSetting.add(getJPanel_SettingValues());
			jHotSetting.add(getJButton_Update());
			jHotSetting.add(getJSeparator1());
			jHotSetting.add(getJLabel5());
			jHotSetting.add(getJLabel6());
		}
		return jHotSetting;
	}

	public JPanel getJPanel_SettingValues() {
		if(jPanel_SettingValues == null) {
			jPanel_SettingValues = new JPanel();
			jPanel_SettingValues.setBounds(31, 99, 250, 238);
			jPanel_SettingValues.add(getJLabel3());
			jPanel_SettingValues.add(getJLabel1());
			jPanel_SettingValues.add(getJTextField_ClientsWeight());
			jPanel_SettingValues.add(getJSlider_ClientsWeight());
			jPanel_SettingValues.add(getJLabel_Empty2());
			jPanel_SettingValues.add(getJLabel2());
			jPanel_SettingValues.add(getJTextField_ValueOfRssi());
			jPanel_SettingValues.add(getJSlider_RssiWeight());
		}
		return jPanel_SettingValues;
	}

	public JButton getJButton_Update() {
		if(jButton_Update == null) {
			jButton_Update = new JButton();
			jButton_Update.setText("UPDATE");
			ImageIcon updateLogo = new ImageIcon("./media/refresh.png");
			jButton_Update.setIcon(updateLogo);
			jButton_Update.setFont(new java.awt.Font("AlArabiya",1,14));
			jButton_Update.setBounds(151, 357, 133, 47);
			jButton_Update.addMouseListener(new MouseAdapter() {
				public void mouseClicked(MouseEvent evt) {
					jButton_UpdateMouseClicked(evt);
				}
			});
		}
		return jButton_Update;
	}

	private JLabel getJLabel1() {
		if(jLabel1 == null) {
			jLabel1 = new JLabel();
			jLabel1.setText("WN = clients weight");
			jLabel1.setPreferredSize(new java.awt.Dimension(142, 25));
			jLabel1.setFont(new java.awt.Font("AlArabiya",0,12));
		}
		return jLabel1;
	}

	public JTextField getJTextField_ClientsWeight() {
		if(jTextField_ClientsWeight == null) {
			jTextField_ClientsWeight = new JTextField(3);
			double d = (double)getJSlider_ClientsWeight().getValue()/100;
			String tmp = ""+d;
			jTextField_ClientsWeight.setText(tmp);
			jTextField_ClientsWeight.setEditable(false);
		}
		return jTextField_ClientsWeight;
	}

	public JSlider getJSlider_ClientsWeight() {
		if(jSlider_ClientsWeight == null) {
			jSlider_ClientsWeight = new JSlider();
			jSlider_ClientsWeight.setMajorTickSpacing(25);
			jSlider_ClientsWeight.setMinorTickSpacing(5);
			jSlider_ClientsWeight.setPaintTrack(true);
			jSlider_ClientsWeight.setPaintTicks(true);
			jSlider_ClientsWeight.setPaintLabels(true);
			jSlider_ClientsWeight.setPreferredSize(new java.awt.Dimension(241, 44));
			int n=(int)(ssp.xmlSynchronized.getWc()*100);
			jSlider_ClientsWeight.setValue(n);
			jSlider_ClientsWeight.setFont(new java.awt.Font("AlArabiya",0,10));
			jSlider_ClientsWeight.addChangeListener(new ChangeListener(){
				public void stateChanged(ChangeEvent e) {
					double d = (double)getJSlider_ClientsWeight().getValue()/100;
					String tmp = ""+d;
					getJTextField_ClientsWeight().setText(tmp);
					getJSlider_RssiWeight().setValue(100-getJSlider_ClientsWeight().getValue());
				}
			});
		}
		return jSlider_ClientsWeight;
	}

	private JLabel getJLabel_Empty2() {
		if(jLabel_Empty2 == null) {
			jLabel_Empty2 = new JLabel();
			jLabel_Empty2.setPreferredSize(new java.awt.Dimension(195, 18));
		}
		return jLabel_Empty2;
	}

	private JLabel getJLabel2() {
		if(jLabel2 == null) {
			jLabel2 = new JLabel();
			jLabel2.setText("WR = RSSI weight");
			jLabel2.setPreferredSize(new java.awt.Dimension(147, 25));
			jLabel2.setFont(new java.awt.Font("AlArabiya",0,12));
		}
		return jLabel2;
	}

	public JTextField getJTextField_ValueOfRssi() {
		if(jTextField_ValueOfRssi == null) {
			jTextField_ValueOfRssi = new JTextField(3);
			double d = (double)getJSlider_RssiWeight().getValue()/100;
			String tmp = ""+d;
			jTextField_ValueOfRssi.setText(tmp);
			jTextField_ValueOfRssi.setEditable(false);
		}
		return jTextField_ValueOfRssi;
	}

	public JSlider getJSlider_RssiWeight() {
		if(jSlider_RssiWeight == null) {
			jSlider_RssiWeight = new JSlider();
			jSlider_RssiWeight.setMaximum(100);
			jSlider_RssiWeight.setMinimum(0);
			jSlider_RssiWeight.setMajorTickSpacing(25);
			jSlider_RssiWeight.setMinorTickSpacing(5);
			jSlider_RssiWeight.setPaintTrack(true);
			jSlider_RssiWeight.setPaintTicks(true);
			jSlider_RssiWeight.setPaintLabels(true);
			int n=(int)(ssp.xmlSynchronized.getWr()*100);
			jSlider_RssiWeight.setValue(n);
			jSlider_RssiWeight.setPreferredSize(new java.awt.Dimension(241, 44));
			jSlider_RssiWeight.setFont(new java.awt.Font("AlArabiya",0,10));
			jSlider_RssiWeight.addChangeListener(new ChangeListener(){
				public void stateChanged(ChangeEvent e) {
					double d = (double)getJSlider_RssiWeight().getValue()/100;
					String tmp = ""+d;
					getJTextField_ValueOfRssi().setText(tmp);
					getJSlider_ClientsWeight().setValue(100-getJSlider_RssiWeight().getValue());
				}
			});
		}
		return jSlider_RssiWeight;
	}

	private JLabel getJLabel3() {
		if(jLabel3 == null) {
			jLabel3 = new JLabel();
			jLabel3.setPreferredSize(new java.awt.Dimension(194, 10));
		}
		return jLabel3;
	}

	private void jButton_UpdateMouseClicked(MouseEvent evt) {
		synchronized(ssp.getLambdaValuesSemaphore()) {
			ssp.xmlSynchronized.setWc(Double.parseDouble(getJTextField_ClientsWeight().getText()));
			System.out.println("Clients weight: "+Double.parseDouble(getJTextField_ClientsWeight().getText()));
			ssp.xmlSynchronized.setWr(Double.parseDouble(getJTextField_ValueOfRssi().getText()));
			System.out.println("Rssi weight: "+Double.parseDouble(getJTextField_ValueOfRssi().getText()));
		}
	}
	
	private JLabel getJLabel4() {
		if(jLabel4 == null) {
			jLabel4 = new JLabel();
			jLabel4.setBounds(13, 17, 394, 29);
			jLabel4.setText("Lambda parameters \"Run Time\" setting:");
			jLabel4.setFont(new java.awt.Font("AlArabiya",1,12));
			jLabel4.setHorizontalAlignment(SwingConstants.CENTER);
		}
		return jLabel4;
	}
	
	private JSeparator getJSeparator1() {
		if(jSeparator1 == null) {
			jSeparator1 = new JSeparator();
			jSeparator1.setBounds(58, 77, 310, 10);
		}
		return jSeparator1;
	}
	
	private JLabel getJLabel5() {
		if(jLabel5 == null) {
			jLabel5 = new JLabel();
			jLabel5.setText("Lambda Value = ( N° of client * WN ) + ( RSSI * WR ) + coding");
			jLabel5.setBounds(47, 50, 338, 15);
			jLabel5.setFont(new java.awt.Font("AlArabiya",2,12));
		}
		return jLabel5;
	}
	
	private JLabel getJLabel6() {
		if(jLabel6 == null) {
			jLabel6 = new JLabel();
			ImageIcon sid = new ImageIcon("./media/sid_medium.png");
			jLabel6.setIcon(sid);
			jLabel6.setBounds(293, 112, 117, 225);
		}
		return jLabel6;
	}
}
